/**
Company: Sarkar software technologys
WebSite: http://www.sarkar.cn
Author: yeganaaa
Date : 5/18/18
Time: 2:35 PM
 */

package Cn.Sarkar.IMS.Entities.DataSources

import Cn.Sarkar.Configuration.makeConfig
import Cn.Sarkar.IMS.Entities.DataSources.Feature.KlaxonJsonSerializer
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import io.ktor.client.features.HttpClientFeature
import io.ktor.client.features.cookies.HttpCookies
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.get
import io.ktor.client.response.HttpResponse
import io.ktor.client.response.HttpResponsePipeline
import io.ktor.util.AttributeKey
import org.slf4j.LoggerFactory
import java.io.File

class HttpDataSource private constructor() {
    data class Configuration(var remoteHost: String = "127.0.0.1", var remotePort: Int = 8080)

    private var configuration = Configuration()
    private val baseUrl = "MMS/Api"

    fun HttpRequestBuilder.configureHostPort(vararg path: String) {
        url {
            host = configuration.remoteHost
            port = configuration.remotePort
            this.path(*path)
        }
    }

    init {
        configuration = makeConfig("Configuration${File.separator}IMSRemoteServices.json", Configuration::class) { Configuration() }
    }

    suspend fun homePage() = client.get<String> { configureHostPort("index.html") }

    suspend fun localizedStrings(code: String = "ug") = client.get<String> {
        configureHostPort("MMS", "Api", "Localization", code, "strings", "strings.json")
    }


    companion object {

        private val client by lazy {

            val logger = LoggerFactory.getLogger(HttpDataSource::class.java)

            HttpClient(CIO) {
                install(HttpCookies)
                install(JsonFeature) {
                    serializer = KlaxonJsonSerializer()
                }
                install(object: HttpClientFeature<Unit, Unit>{
                    override val key: AttributeKey<Unit> = AttributeKey("Error handling")

                    override fun install(feature: Unit, scope: HttpClient) {
                        scope.responsePipeline.intercept(HttpResponsePipeline.After){
                            if (subject.response is HttpResponse){
                                logger.error("\n*****************************Brgin For Http Request Error**************************")
                                logger.error("\n Request url: {},\n method: {},\n header: {}", context.request.url, context.request.method, context.request.headers)
                                logger.error("\n***********************************************************************************")
                                logger.error("\n Response header: {},\n StatusCode: {}", context.response.headers, context.response.status)
                                logger.error("\n*****************************End For Http Request Error****************************")
                            }
                        }
                    }

                    override suspend fun prepare(block: Unit.() -> Unit) {

                    }

                })
            }
        }

        fun new() = HttpDataSource()
    }
}